﻿/// <reference path="typings/jquery/jquery.d.ts" />
/// <reference path="typings/jquery/jqueryui.d.ts" />
/// <reference path="typings/jquery/jquery.tmpl.d.ts" />
/// <reference path="typings/linq.d.ts" />
/// <reference path="typings/linq.jquery.d.ts" />

interface JQuery {
    fileupload: any;
    sort: any;
}

interface JQueryStatic {
    fileDownload: any;
    Dialog: any;
}

declare var OData: any;

module CloudStorageLight {

    export class FileItem {
        public Id: string;
        public Type: string;
        public Directory: string;
        public Title: string;
        public SearchContent: string;
        public Owner: string;
        public CheckoutUser: string;
        public LastModified: Date;
        public Remark: string;
        public Path: string;
        public Length: string;
        public Url(): string {
            return window.location.protocol + "//" +window.location.host + "/f" + this.Path;
        }
        public SizeString(): string {
            return this.formatFileSize(this.Length);
        }

        public Icon(): string {
            if (this.Type == "Directory") return "icon-folder-2";
            if (this.pathEndsWith(".doc") || this.pathEndsWith(".docx")) {
                return "icon-file-word";
            }
            if (this.pathEndsWith(".ppt") || this.pathEndsWith(".pptx")) {
                return "icon-file-powerpoint";
            }
            if (this.pathEndsWith(".xls") || this.pathEndsWith(".xlsx")) {
                return "icon-file-excel";
            }
            if (this.pathEndsWith(".pdf")) {
                return "icon-file-pdf";
            }
            if (this.pathEndsWith(".zip")) {
                return "icon-file-zip";
            }
            return "icon-file";
        }

        private pathEndsWith(suffix: string) : boolean {
            return this.Path.indexOf(suffix, this.Path.length - suffix.length) !== -1;
        }

        private formatFileSize(bytes: any) {
            if (typeof bytes !== 'number') {
                return '';
            }

            if (bytes >= 1000000000) {
                return (bytes / 1000000000).toFixed(2) + ' GB';
            }

            if (bytes >= 1000000) {
                return (bytes / 1000000).toFixed(2) + ' MB';
            }

            return (bytes / 1000).toFixed(2) + ' KB';
        }

    }

    export class FileAccessToken {

        public role: string;
        public inUse: boolean;
        public canRead: boolean;
        public canWrite: boolean
        public canModify: boolean;
        public canControl: boolean;

        constructor(tokensString: string = null) {
            if (tokensString) {
                var items = tokensString.split(":");
                if (items.length != 2) throw new Error("invalid token string");
                this.role = items[0];
                var access: string = items[1];
                if (access.indexOf("r") >= 0) this.canRead = true;
                if (access.indexOf("w") >= 0) this.canWrite = true;
                if (access.indexOf("m") >= 0) this.canModify = true;
                if (access.indexOf("c") >= 0) this.canControl = true;
                this.inUse = true;
            }
        }

        public toString(): string {
            return this.role + ":" + (this.canRead ? "r" : "") + (this.canWrite ? "w" : "") + (this.canModify ? "m" : "") + (this.canControl ? "c" : "");
        }
    }

    export class StorageController {

        ///
        /// メッセージ定義
        ///
        public static msgRoleSelectorTitle: string;
        public static msgDownloadComplete: string;
        public static msgDownloadError: string;
        public static msgErrGeneral: string;
        public static msgPleaseChecked: string;
        public static msgConfirmDelete: string;
        public static msgCmdNewFolder: string;
        public static msgCmdFolderSetup: string;
        public static msgCmdUserList: string;
        public static msgConfirmDeleteFolder: string;
        public static msgChangePassword: string;
        public static msgUploading: string;
        public static msgDownloading: string;
        public static msgProcessing: string;
        public static msgCancel: string;
        public static msgPleaseReadMail: string;
        public static msgDuplicateRole: string;

        public static msgEditingOtherUser: string;
        public static msgUploadedCheckin: string;
        public static msgCheckoutAndDownload: string;
        public static msgUserInfoSettings: string;
        public static msgConfirmDeleteUser: string;
        public static msgConfirmDownloadZip: string;
        public static msgItemUrl: string;
        public static msgCmdRename: string;
        public static msgCmdMove: string;
        public static msgConfirmDeleteFile: string;

        public static msgFoundItems: string;
        public static msgFoundOver: string;
        public static msgNotFound: string;

        ///
        /// 共通変数
        ///
        public static contentMenuTarget: JQuery;
        private static uploadQue: any[] = [];
        private static currentUpload: any;
        private static allSuccess: boolean;
        public static xhrPool: any[] = [];


        public static getFiles(target: JQuery, path: string, start:number=0, size:number=200): void {
            StorageController.blockUI(null);
            $("#file-items").empty();
            $(".search-result-message").empty();
            $.ajax(StorageController.getODataUrl(null, null) + "?$filter=Directory eq '" + path + "'&$skip=" + start.toString() + "&$top=" + (size + 1).toString(), {
                type: "GET",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    var cont = $("#file-items");
                    if (data.value) {
                        Enumerable.from(data.value)
                            .orderBy(function (x: any) { return x.Type; })
                            .thenBy(function (x: any) { return x.Title; })
                            .take(size)
                            .doAction(function (x) {
                                var obj = <FileItem>$.extend(new FileItem(), x);
                                var ele = $("#fileitem-template").tmpl(obj);
                                cont.append(ele);
                            }).toArray();
                        if (data.value.length > size) {
                            var more = $("#fileitem-more-template").tmpl();
                            cont.append(more);
                        }
                    } else if (data.error && data.error.message) {
                        cont.append(data.error.message);
                    }

                    StorageController.bindItemEvent();
                    StorageController.unblockUI();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var cont = $("#file-items");
                    cont.append(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
                dataType: "json"
            });
        }

        public static searchFiles(target: JQuery, path: string, query : string, size: number= 200): void {
            StorageController.blockUI(null);
            $("#file-items").empty();
            $(".search-result-message").empty();
            $.ajax(StorageController.getODataUrl(null, null) + "?$filter=startswith(Directory,'" + path + "')&$search='" + encodeURIComponent(query)  + "'&$top=" + (size + 1).toString(), {
                type: "GET",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    var cont = $("#file-items");
                    if (data.value) {
                        if (data.value.length == 0) {
                            var message = $(".search-result-message");
                            message.append(StorageController.formatString(StorageController.msgNotFound,query));
                        } else {
                            var message = $(".search-result-message");
                            if (data.value.length > size) {
                                message.append(StorageController.formatString(StorageController.msgFoundOver, size));
                            } else {
                                message.append(StorageController.formatString(StorageController.msgFoundItems, data.value.length));
                            }
                            Enumerable.from(data.value)
                                .take(size)
                                .doAction(function (x) {
                                    var obj = <FileItem>$.extend(new FileItem(), x);
                                    var ele = $("#fileitem-template").tmpl(obj);
                                    cont.append(ele);
                                }).toArray();
                        }
                    } else if (data.error && data.error.message) {
                        cont.append(data.error.message);
                    }
                    StorageController.bindItemEvent();
                    StorageController.unblockUI();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var message = $(".search-result-message");
                    message.append(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
                dataType: "json"
            });
        }

        ///
        /// 表示後のイベント割り当て
        ///
        public static bindItemEvent(cont:JQuery= null): void {

            var tapTimeoutId = 0;

            if (!cont) cont = $("#folder-cont");

            cont.find('.item-name').unbind().click(function (event) {
                var target = $(this).closest(".list-content").find(".item-checkbox");
                if (target.is(":visible")) target.prop("checked", !target.prop("checked"));
            });


            cont.find('.list-content').unbind().click(function (e) {
                $(".list-content").removeClass("open");

                $(this).find(".list-content").addClass("open");
                StorageController.contentMenuTarget = $(this);
                StorageController.showContextMenu(StorageController.contentMenuTarget);

            });


            $("#showurl-context-command").unbind().click(function () {
                $.Dialog({
                    flat: true,
                    overlay: true,
                    shadow: true,
                    title: CloudStorageLight.StorageController.msgItemUrl,
                    width: 300,
                    height: 100,
                    content: "<input type='text' readonly='readonly' id='itemUrl' style='width:100%;' value='" + StorageController.contentMenuTarget.find(".blobfile").attr("data-href") + "' />",
                    padding: 10,
                    onShow: function (_dialog) {
                        $("#itemUrl").focus();
                    }
                });
            });

            $(".morePage").unbind().click(function () {
                CloudStorageLight.StorageController.morePage();
            });

            //$(window).unbind("bottom",true).one('bottom', function () {
            //    if ($(".morePage").length > 0) {
            //        CloudStorageLight.StorageController.morePage();
            //    }
            //});


        }

        ///
        /// コンテキストメニューの表示
        ///
        public static showContextMenu(contentMenuTarget: JQuery): void {

            if (contentMenuTarget.find(".list-context-menu").length == 0) return;
            $("#contextMenu-dialog").appendTo(contentMenuTarget.find(".list-context-menu"));
            $("#contextMenu-dialog").show();

            var checkout = contentMenuTarget.find(".icon-pop-out");
            if (checkout.length == 0) {
                $("#checkout-context-command").show();
                $("#checkin-context-command").hide();
            } else {
                $("#checkout-context-command").hide();
                $("#checkin-context-command").show();
            }
        }

        ///
        /// 次のデータの取得
        ///
        public static morePage(size:number=200): void {
            var start = $("#file-items>.list").length;

            var path = $("#currentPath").val();

            $(".morePage").empty().append('<img src="/Content/Images/ajax-loader.gif">');
            var self = $(this);
            $.ajax(StorageController.getODataUrl(null, null) + "?$filter=Directory eq '" + path + "'&$skip=" + start.toString() + "&$top=" + (size + 1).toString(), {
                type: "GET",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    $(".morePage").remove();
                    $(data).children().appendTo($("#folder-cont"));
                    var cont = $("#file-items");
                    Enumerable.from(data.value)
                        .take(size)
                        .doAction(function (x) {
                            var obj = <FileItem>$.extend(new FileItem(), x);
                            var ele = $("#fileitem-template").tmpl(obj);
                            cont.append(ele);
                        }).toArray();
                    if (data.value.length > size) {
                        var more = $("#fileitem-more-template").tmpl();
                        cont.append(more);
                    }
                    StorageController.bindItemEvent();
                    StorageController.unblockUI();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var cont = $("#file-items");
                    cont.append(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
                dataType: "json"
            });

        }

        ///
        /// アップロード
        ///
        public static upload(data: any): void {
            StorageController.uploadQue.push(data);
            if (!StorageController.currentUpload) {
                StorageController.currentUpload = data;
                StorageController.blockUI(null);
                setTimeout(function () {
                    StorageController.uploadItem();
                }, 10);
            }
        }

        private static uploadItem(): void {
            if (StorageController.uploadQue.length == 0) {
                StorageController.currentUpload = null;
                StorageController.refresh();
            } else {
                StorageController.currentUpload = StorageController.uploadQue.shift();
                $('#prog-message').text(StorageController.formatString(StorageController.msgUploading, [StorageController.currentUpload.files[0].name, StorageController.uploadQue.length + 1]));

                setTimeout(function () {
                    StorageController.currentUpload.submit()
                        .error(function (jqXHR, textStatus, errorThrown) {
                            //TODO大量ロードの時のエラー処理8/29
                            if (textStatus != "abort") {
                                alert(CloudStorageLight.StorageController.msgErrGeneral + " " + StorageController.currentUpload.files[0].name);
                                StorageController.uploadItem();
                            } else {
                                StorageController.uploadQue = [];
                                StorageController.currentUpload = null;
                            }
                        })
                        .complete(function (result, textStatus, jqXHR) {
                            if (textStatus == "error") return;
                            if (textStatus != "abort") {
                                if (!result.responseJSON.status) {
                                    alert(result.responseJSON.data + " " + StorageController.currentUpload.files[0].name);
                                }
                                StorageController.uploadItem();
                            } else {
                                StorageController.uploadQue = [];
                                StorageController.currentUpload = null;
                            }
                        });
                }, 10);
            }
        }

        ///
        /// 名前変更
        ///
        public static rename(target: JQuery, srcName: string, distName: string): void {
            if (!StorageController.startProcess(null, null, true, true)) return;
            StorageController.renameItem(target.find(".item-checkbox"), srcName, distName, function () {
                StorageController.refresh();
            });
        }

        ///
        /// 名前変更
        ///
        public static renameItem(target: JQuery, srcName: string, distName: string, callback= null): void {
            var statusText = target.closest(".list").find(".list-remark");
            statusText.text("");
            var jsonData = JSON.stringify({ targetId: distName });
            $.ajax(StorageController.getODataUrl(target.attr("name"), "Rename"), {
                type: "POST",
                contentType: "application/json; charset=utf-8",
                data: jsonData,
                success: function (data) {
                    StorageController.endProcessing();
                    if (callback) callback();
                },
                error: function (xhr, textStatus, errorThrown) {
                    statusText.text(StorageController.getErrorMessage(xhr));
                    StorageController.endProcessing();
                },
            });

        }

        ///
        /// 移動（チェックボックスで指定されたアイテム）
        ///
        public static move(distName: string): void {
            if (!StorageController.startProcess(null, function () { StorageController.refresh(); })) return;
            $(".item-checkbox:checked").each(function () {
                StorageController.renameItem($(this), $(this).attr("name"), distName);
            });
        }

        ///
        /// 削除（チェックボックスで指定されたアイテム）
        ///
        public static remove(removing= null): void {
            if (!StorageController.startProcess(function () {
                return confirm(StorageController.formatString(StorageController.msgConfirmDelete, $(".item-checkbox:checked").length));
            })) return;
            $(".item-checkbox:checked").each(function () {
                StorageController.removeItem($(this), removing);
            });
        }

        ///
        /// 削除（個別指定）
        ///
        public static removeOne(target: JQuery, removing= null): void {
            if (!StorageController.startProcess(function () {
                return confirm(StorageController.formatString(StorageController.msgConfirmDeleteFile, target.find(".item-name").text()));
            }, null, true, true)) return;
            StorageController.removeItem(target.find(".item-checkbox"), removing);
        }

        private static removeItem(target: JQuery, removing= null): void {

            //OData.request({
            //    requestUri: StorageController.getODataUrl(target.attr("name"), null),
            //    headers: { "DataServiceVersion": "3.0" },
            //    method: "DELETE",
            //}, function (data, response) {
            //    var contents = target.closest(".list");
            //    if (removing) removing();
            //    contents.remove();
            //    StorageController.endProcessing();
            //}, function (err) {
            //    var statusText = target.closest(".list").find(".list-remark");
            //    statusText.text(err.message);
            //    StorageController.endProcessing();
            //});


            $.ajax(StorageController.getODataUrl(target.attr("name"), null), {
                type: "DELETE",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    var contents = target.closest(".list");
                    if (removing) removing();
                    contents.remove();
                    StorageController.endProcessing();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var statusText = target.closest(".list").find(".list-remark");
                    statusText.text(StorageController.getErrorMessage(xhr));
                    StorageController.endProcessing();
                },
            });
        }

        ///
        /// ダウンロード（チェックボックスで指定されたアイテム）
        ///
        public static download(): void {

            if (!StorageController.startProcess(null, null, false)) return;
            var que: JQuery[] = [];
            $(".item-checkbox:checked").each(function () {
                que.push($(this).closest(".blobfile"));
            });
            StorageController.downloadfile(que);

        }

        ///
        /// ダウンロード（個別指定）
        ///
        public static downloadOne(target: JQuery): void {
            if (!StorageController.startProcess(null, null, false, true)) return;
            var que: JQuery[] = [];
            que.push(target.find(".blobfile"));
            StorageController.downloadfile(que);

        }

        ///
        /// ダウンロード ZIP（チェックボックスで指定されたアイテム）
        ///
        public static downloadZip(): void {
            if (!StorageController.startProcess()) return;
            var files = {};
            $(".item-checkbox:checked").each(function (idx) {
                files["file" + idx.toString()] = $(this).attr("name");
            });

            setTimeout(function () {

                $.fileDownload(
                    StorageController.getHelperUrl("/DownloadAsZip"), {
                        httpMethod: "POST",
                        data: files,
                        successCallback: function (url) {
                            StorageController.endProcessing(true);

                        },
                        failCallback: function (html, url) {
                            StorageController.endProcessing(true);
                        }
                    });
            }
                , 100);
        }
 
        private static downloadfile(que: JQuery[]): void {
            if (que.length == 0) {
                StorageController.endProcessing(true);
                return;
            }
            var target = que.shift();
            var url = target.data("href") + "?attachment=true"
            $('#prog-message').text(StorageController.formatString(StorageController.msgDownloading, [target.find(".item-name").text(), que.length + 1]));
            setTimeout(function () {

                $.fileDownload(
                    url, {
                        successCallback: function (url) {
                            StorageController.downloadfile(que);
                            var statusText = target.find(".list-remark");
                            statusText.text(CloudStorageLight.StorageController.msgDownloadComplete);
                        },
                        failCallback: function (html, url) {
                            StorageController.downloadfile(que);
                            var statusText = target.find(".list-remark");
                            statusText.text(CloudStorageLight.StorageController.msgDownloadError);
                        }
                    });
            }, 100);
        }

        ///
        /// フォルダ作成
        ///
        public static createNewFolder(): void {
            $('#create-folder-dialog').dialog("close");
            StorageController.blockUI(null);
            var jsonData = JSON.stringify({ directoryName: $('#newFolderName').val() });
            $.ajax(StorageController.getODataUrl($("#currentPath").val() , "CreateDirectory"), {
                type: "POST",
                contentType: "application/json; charset=utf-8",
                data: jsonData,
                success: function (data) {
                    StorageController.unblockUI();
                    StorageController.refresh();
                },
                error: function (xhr, textStatus, errorThrown) {
                    alert(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
                dataType: "json"
            });
        }

        ///
        /// フォルダ削除
        ///
        public static removeFolder(): void {
            var path: string = $("#currentPath").val();
            if (!confirm(StorageController.formatString(StorageController.msgConfirmDeleteFolder, path))) {
                return;
            }

            StorageController.blockUI(null);
            $.ajax(StorageController.getODataUrl(path, null), {
                type: "DELETE",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    window.location.href = StorageController.getParentFolderPath(window.location.href);
                },
                error: function (xhr, textStatus, errorThrown) {
                    alert(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
            });
        }


        private static setAccessToken(target: JQuery, token: FileAccessToken) {
            target.find(".accessToken-inuse").prop("checked", token.inUse);  
            target.find(".accessToken-name").val( token.role);  
            target.find(".accessToken-can-read").prop("checked", token.canRead);  
            target.find(".accessToken-can-write").prop("checked", token.canWrite);  
            target.find(".accessToken-can-modify").prop("checked", token.canModify);  
            target.find(".accessToken-can-control").prop("checked", token.canControl);  
        }

        ///
        /// フォルダ設定表示
        ///
        public static setupFolder(): void {
            StorageController.blockUI(null);
            var path: string = $("#currentPath").val();
            $.ajax(StorageController.getODataUrl($("#currentPath").val() , "GetAccessControl"), {
            //$.ajax(StorageController.getHelperUrl("/GetAccessControl") + "?id=" + path, {
                type: "GET",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    var idx = 0;
                    var guest: FileAccessToken = null;
                    var everyone: FileAccessToken = null;
                    $("#directory-access-list tr.token-line").remove();
                    if (data.value) {
                        $.each(data.value.split(","), function () {
                            var access = new FileAccessToken(this);
                            if (access.role != "everyone" && access.role != "guest") {
                                var ele = $("#accesstoken-template").tmpl({ index: idx++, name: access.role });
                                $("#directory-access-list").append(ele);
                                StorageController.setAccessToken(ele, access);
                            } else {
                                if (access.role == "everyone") everyone = access;
                                if (access.role == "guest") guest = access;
                            }
                        });
                    }
                    for (var i = 0; i < 3; i++) {
                        var ele = $("#accesstoken-template").tmpl({ index: idx++, name: "" });
                        $("#directory-access-list").append(ele);
                    }

                    var ele = $("#accesstoken-template").tmpl({ index: idx++, name: "everyone" });
                    $("#directory-access-list").append(ele);
                    if (everyone) StorageController.setAccessToken(ele, everyone);

                    ele = $("#accesstoken-template").tmpl({ index: idx++, name: "guest" });
                    $("#directory-access-list").append(ele);
                    if (guest) StorageController.setAccessToken(ele, guest);

                    StorageController.unblockUI();
                },
                error: function (xhr, textStatus, errorThrown) {
                    alert(StorageController.getErrorMessage(xhr));
                    StorageController.unblockUI();
                },
            });


            $("#directorySettings").dialog({
                width: 800,
                height: 500,
                modal: true,
                title: StorageController.msgCmdFolderSetup + " " + $("#currentPath").val(),
            });

        }

        ///
        /// フォルダ設定実行
        ///
        public static updateFolder(): void {
            StorageController.blockUI(null);

            var accessTokens:string[] = [];

            $("#directory-access-list .accessToken-inuse").each(function () {
                var inuse = $(this);
                var parent = $(this).closest("tr");
                if (inuse.prop("checked") && parent.find(".accessToken-name").val()) {
                    var token = new FileAccessToken();
                    token.inUse = true;
                    token.role = parent.find(".accessToken-name").val();
                    token.canRead = parent.find(".accessToken-can-read").prop("checked");
                    token.canWrite = parent.find(".accessToken-can-write").prop("checked");
                    token.canModify = parent.find(".accessToken-can-modify").prop("checked");
                    token.canControl = parent.find(".accessToken-can-control").prop("checked");
                    accessTokens.push(token.toString());
                }
            });

            var jsonData = JSON.stringify({ accessTokens: accessTokens.join(",") });

            $.ajax(StorageController.getODataUrl($("#currentPath").val(), "SetAccessControl"), {
                type: "POST",
                data: jsonData,
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    StorageController.unblockUI();
                    $("#directorySettings").dialog("close");
                },
                error: function (xhr, textStatus, errorThrown) {
                    StorageController.unblockUI();
                    alert(StorageController.getErrorMessage(xhr));
                },
            });
        }

        ///
        /// フォルダ設定閉じる
        ///
        public static closeUpdateFolderDialog(): void {
            $("#directorySettings").dialog("close");
        }

        ///
        /// 検索処理
        ///
        public static search(query: string, current: string, cont: JQuery): void {

            StorageController.searchFiles(cont, current, query);
        }

 
        public static hideContextMenu(contentMenuTarget: JQuery): void {
            $("#contextMenu-dialog").appendTo($("#folder-cont"));
            $("#contextMenu-dialog").hide();

        }

        ///
        /// チェックアウト
        ///
        public static checkout(target: JQuery): void {
            if (!StorageController.startProcess(null, null, true, true)) return;
            StorageController.checkoutItem(target.find(".item-checkbox"));
        }

        public static checkoutItem(target: JQuery): void {
            StorageController.allSuccess = true;
            $.ajax(StorageController.getODataUrl(target.attr("name"), "Checkout"), {
                type: "POST",
                success: function (data) {
                    var contents = target.closest(".list");
                    var obj = <FileItem>$.extend(new FileItem(), data);
                    var ele = $("#fileitem-template").tmpl(obj);
                    contents.html(ele.html());
                    StorageController.bindItemEvent(contents);
                    StorageController.endProcessing();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var statusText = target.closest(".list").find(".list-remark");
                    statusText.text(StorageController.getErrorMessage(xhr));
                    StorageController.endProcessing();
                    StorageController.allSuccess = false;
                },
                dataType: "json"
            });
        }

        ///
        /// チェックイン
        ///
        public static checkin(target: JQuery): void {
            if (!StorageController.startProcess(null, null, true, true)) return;
            StorageController.checkinItem(target.find(".item-checkbox"));
        }

        public static checkinItem(target: JQuery): void {
            var self = $(this);
            $.ajax(StorageController.getODataUrl(target.attr("name"), "Checkin"), {
                type: "POST",
                success: function (data) {
                    var contents = target.closest(".list");
                    var obj = <FileItem>$.extend(new FileItem(), data);
                    var ele = $("#fileitem-template").tmpl(obj);
                    contents.html(ele.html());
                    StorageController.bindItemEvent(contents);
                    StorageController.endProcessing();
                },
                error: function (xhr, textStatus, errorThrown) {
                    var statusText = target.closest(".list").find(".list-remark");
                    statusText.text(StorageController.getErrorMessage(xhr));
                    StorageController.endProcessing();
                },
                dataType: "json"
            });
        }


        ///
        /// ユーリティティ
        ///

        public static getHelperUrl(url: string): string {
            return "/Helper" + url;
        }
        public static getODataUrl(path: string, action: string): string {
            var url = "/odata/Data";
            if (path) {
                url += "('" + path.replace(/\./g, "*").replace(/\//g,"|") + "')"
            }
            if (action) {
                url += "/StorageService." + action;
            }
            return url;
        }

        private static abortAll(): void {
            $(StorageController.xhrPool).each(function (idx, jqXHR: any) {
                jqXHR.abort();
            });
            CloudStorageLight.StorageController.xhrPool = [];
        }

        private static getParentFolderPath(path: string) {
            var items = path.split("?")[0].split("/");
            if (items.length <= 1) return "/";
            if (items.pop() == "") items.pop();
            return items.join("/") + "/";
        }

        private static formatString(fmt: string, a: any): string {
            var rep_fn = undefined;

            var rep_fn = undefined;

            if (typeof a == "object") {
                rep_fn = function (m, k) { return a[k]; }
            }
            else {
                var args = arguments;
                rep_fn = function (m, k) { return args[parseInt(k) + 1]; }
            }

            return fmt.replace(/\{(\w+)\}/g, rep_fn);
        }

        private static refresh(path: string = null): void {
            StorageController.blockUI(null);
            if (path) {
                StorageController.getFiles($("#file-items"), path);
            } else {
                StorageController.getFiles($("#file-items"), $("#currentPath").val());
            }
            $('body,html').animate({
                scrollTop: 0
            }, 100);
        }

        private　static blockUI(cont: JQuery): void {
            $('#freezePanel').remove();
            if (!cont) cont = $('#maindiv');
            var wrap = $('<div id="freezePanel" style="postion:relative;height:0;width:0;"><div class="freezePaneOn"></div><div class="innerFreezePane"><div class="prog-cont"><div id="prog-message">' + StorageController.msgProcessing + '</div></div><div><img src="/Content/Images/ajax-loader.gif"></div><div><a id="prog-cancel" href="javascript:void(0);">' + StorageController.msgCancel + '</a></div></div></div>');
            $(cont).append(wrap);
            wrap.find(".freezePaneOn").height(cont.height());
            wrap.find("#prog-cancel").click(function () {
                StorageController.abortAll();
                StorageController.unblockUI();
            });
            $('#freezePaneOn').focus();
        }

        private　static unblockUI(): void {
            $('#freezePanel').remove();
        }

        private　static startProcess(confirm: any= null, callback: any= null, unblockAjaxStop: boolean = true, skipAlert: boolean= false): boolean {
            if (!skipAlert && $(".item-checkbox:checked").length == 0) {
                alert(StorageController.msgPleaseChecked);
                return false;
            } else {
                if (confirm && !confirm()) return;
                StorageController.blockUI(null);
                if (unblockAjaxStop) {
                    $(document).one("ajaxStop", function () {
                        StorageController.unblockUI();
                        if (callback) { callback(); }
                    });
                }
                StorageController.clearMessage();
                return true;
            }
        }

        private　static clearMessage(): void {
            $(".item-checkbox").each(function () {
                var statusText = $(this).closest(".list").find(".list-remark");
                statusText.text("");
            });
            $(".search-result-message").empty();
        }

        private　static endProcessing(force: boolean= false): void {
            if (force) StorageController.unblockUI();
        }

        private static endsWith(str: string, suffix: string): boolean {
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        private static getErrorMessage(xhr): string {
            try {
                var responseJSON = <any>$.parseJSON(xhr.responseText);
                if (responseJSON && responseJSON.error && responseJSON.error.message) {
                    return responseJSON.error.message;
                } else {
                    return StorageController.msgErrGeneral;
                }
            } catch (e) {
                return StorageController.msgErrGeneral;
            };
        }
    }

}

$(function () {

    $.ajaxSetup({
        beforeSend: function (jqXHR) {
            CloudStorageLight.StorageController.xhrPool.push(jqXHR);
        },
        complete: function (jqXHR) {
            var index = CloudStorageLight.StorageController.xhrPool.indexOf(jqXHR);
            if (index > -1) {
                CloudStorageLight.StorageController.xhrPool.splice(index, 1);
            }
        }
    });

    $('#search').click(function () {
        CloudStorageLight.StorageController.search($("#query").val(), $("#currentPath").val(), $("#file-items"));
    });

    $("#query").keypress(function (e) {
        if (e.keyCode == 13) {
            CloudStorageLight.StorageController.search($("#query").val(), $("#currentPath").val(), $("#file-items"));
        }
    });

    $('#newfolder-command').click(function () {
        $('#create-folder-dialog').dialog({
            modal: true,
            title: CloudStorageLight.StorageController.msgCmdNewFolder,
        });
    });
    $('#removefolder-command').click(function () {
        CloudStorageLight.StorageController.removeFolder();
    });

    $('#rename-context-command').click(function () {
        $("#renameSrcPath").val(CloudStorageLight.StorageController.contentMenuTarget.find(".item-checkbox").attr("name"));
        $("#renameDistName").val(CloudStorageLight.StorageController.contentMenuTarget.find(".item-name").text());
        $("#rename-directory-list").load(CloudStorageLight.StorageController.getHelperUrl("/DirectoryDropDownList") + "?name=renameDistDirectory&id=" + $("#currentPath").val());
        $('#rename-dialog').dialog({
            modal: true,
            width: 500,
            title: CloudStorageLight.StorageController.msgCmdRename,
        });
    });

    $('#rename-command').click(function () {
        CloudStorageLight.StorageController.rename(CloudStorageLight.StorageController.contentMenuTarget,
            $("#renameSrcPath").val(), $("#renameDistDirectory").val() + $("#renameDistName").val());
        $('#rename-dialog').dialog("close");
    });

    $('#move-command').click(function () {
        $("#move-directory-list").load(CloudStorageLight.StorageController.getHelperUrl("/DirectoryDropDownList") + "?name=moveDistDirectory&id=" + $("#currentPath").val());

        $('#move-dialog').dialog({
            modal: true,
            width: 400,
            title: CloudStorageLight.StorageController.msgCmdMove,
        });
    });
    $('#move-exec-command').click(function () {
        CloudStorageLight.StorageController.move($("#moveDistDirectory").val());
        $('#move-dialog').dialog('close');
    });

    $('#upload-command').click(function () {
        $('#upl').click();
    });



    $('#remove-command').click(function () {
        CloudStorageLight.StorageController.remove();
    });

    $('#remove-context-command').click(function (e) {
        CloudStorageLight.StorageController.removeOne(CloudStorageLight.StorageController.contentMenuTarget, function () {
            CloudStorageLight.StorageController.hideContextMenu(CloudStorageLight.StorageController.contentMenuTarget);
        });
        e.stopPropagation();
    });

    $('#download-command').click(function () {
        if ($(".item-checkbox:checked").length > 1) {
            $("#download-confirm-dialog").dialog({
                modal: true,
            });

        } else {
            CloudStorageLight.StorageController.download();
        }
    });

    $('#download-context-command').click(function (e) {
        CloudStorageLight.StorageController.downloadOne(CloudStorageLight.StorageController.contentMenuTarget);
        CloudStorageLight.StorageController.hideContextMenu(CloudStorageLight.StorageController.contentMenuTarget);
        e.stopPropagation();
    });
    $('#download-zip-command').click(function () {
        CloudStorageLight.StorageController.downloadZip();
        $("#download-confirm-dialog").dialog("close");
    });
    $('#download-files-command').click(function () {
        CloudStorageLight.StorageController.download();
        $("#download-confirm-dialog").dialog("close");
    });

    $('#checkout-context-command').click(function (e) {
        CloudStorageLight.StorageController.checkout(CloudStorageLight.StorageController.contentMenuTarget);
        CloudStorageLight.StorageController.hideContextMenu(CloudStorageLight.StorageController.contentMenuTarget);
        e.stopPropagation();
    });

    $('#checkin-context-command').click(function (e) {
        CloudStorageLight.StorageController.checkin(CloudStorageLight.StorageController.contentMenuTarget);
        CloudStorageLight.StorageController.hideContextMenu(CloudStorageLight.StorageController.contentMenuTarget);
        e.stopPropagation();
    });



    $('#create-newFolder').click(function () {
        CloudStorageLight.StorageController.createNewFolder();

    });

    $('#folder-setup-command').click(function () {
        CloudStorageLight.StorageController.setupFolder();
    });

    $('#selectall-command').click(function () {
        $(".blobfile .item-checkbox").prop("checked", true);
    });
    $('#unselectall-command').click(function () {
        $(".blobfile .item-checkbox").prop("checked", false);
    });

});
